/**
 * 
 */
package info.niwota.web.apache;

import info.niwota.commons.acl.AccessControl;
import info.niwota.web.ApplicationContext;
import info.niwota.web.Debug;
import info.niwota.web.Preferences;
import info.niwota.web.Session;
import info.niwota.web.SessionManager;
import info.niwota.web.user.UserManager;

import java.io.IOException;
import java.util.Locale;

import org.jivesoftware.smack.util.StringUtils;

import x.org.apache.http.HttpException;
import x.org.apache.http.HttpRequest;
import x.org.apache.http.HttpResponse;
import x.org.apache.http.protocol.HttpContext;
import x.org.apache.http.protocol.HttpRequestHandler;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

/**
 * @author qiangli
 * 
 */
public class HttpAdapter implements HttpRequestHandler {

	private static final String TAG = "HttpAdapter";

	private final HttpDispatcher dispatcher;

	// final ProxyHandler proxy;
	
	private Context ctx;
	
	public HttpAdapter(Context ctx) {
		this.dispatcher = new HttpDispatcher(ctx);
		
		this.ctx = ctx;
	}

	public void handle(HttpRequest request, HttpResponse response,
			HttpContext context) throws IOException, HttpException {
		
		final String uri = request.getRequestLine().getUri();
		final String method = request.getRequestLine().getMethod().toUpperCase(
				Locale.ENGLISH);
		
		if (Debug.DEBUG) {
			Log.d(TAG, "handle " + method + " " + uri );
		}
		
		//
		final String peer = (String) context.getAttribute(SessionManager.WEB_PID_KEY);
		
		autoLogin(peer, context);

		//
		final String target = request.getRequestLine().getUri();
		if (Debug.DEBUG) {
			Log.d(TAG, "handle " + target +" peer: " + peer);
		}
		
		final String jid = ApplicationContext.getJid();
		response.addHeader("X-Peer-Id", jid);
		
		//
		dispatcher.handle(target, request, response, context);
	}


	/**
	 * Auto login peer (over xmpp) and assign group as follows: shared, if found
	 * in user list and shared access is enabled. public, if public access is
	 * enabled otherwise none.
	 * 
	 * master access is not allowed via xmpp connection
	 * 
	 * @param peer
	 * @param context
	 * @throws IOException
	 * @throws Exception
	 */
	private boolean autoLogin(String peer, HttpContext context)
			throws IOException {
		Session s = (Session) context.getAttribute(SessionManager.SESSION_KEY);
		if (s == null) {
			s = SessionManager.create();
		}
		if (s.authenticated) {
			Log.d(TAG, "autoLogin peer was authenticated: " + peer);
			return true;
		}
		if (Debug.DEBUG) {
			Log.d(TAG, "autoLogin peer: " + peer);
		}
		
		if (TextUtils.isEmpty(peer)) {
			return false;
		}
		String user = StringUtils.parseBareAddress(peer);
		
		boolean found = UserManager.exists(ctx, user);

		// site access control
		boolean[] access = Preferences.getAccess(ctx);
		boolean shared = access[AccessControl.ACCESS_SHARED];
		boolean pub = access[AccessControl.ACCESS_PUBLIC];
		// no master access over xmpp

		s.user = user;
		s.authenticated = (found);
		// assign group
		final int defgroup = (pub ? AccessControl.ACCESS_PUBLIC
				: AccessControl.ACCESS_NONE);
		s.group = (found && shared ? AccessControl.ACCESS_SHARED : defgroup);

		context.setAttribute(SessionManager.SESSION_KEY, s);

		if (Debug.DEBUG) {
			Log.d(TAG, "user " + s.user + " auto signed in " + s.authenticated
					+ " as group: " + s.group);
		}

		return found;
	}
}
